/*
 * Copyright 2002-2022 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.config;

import lombok.SneakyThrows;
import org.apache.activemq.broker.BrokerService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.Lifecycle;
import org.springframework.context.SmartLifecycle;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
import org.springframework.messaging.simp.broker.BrokerAvailabilityEvent;
import org.springframework.messaging.simp.stomp.StompBrokerRelayMessageHandler;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * Integration tests for {@link StompBrokerRelayMessageHandler} running against ActiveMQ.
 *
 * @author Rossen Stoyanchev
 * @author Sam Brannen
 */
//@Component
public class StompBrokerRelayMessageHandlerIntegrationConfig implements SmartLifecycle {

    private static final Log logger = LogFactory.getLog(StompBrokerRelayMessageHandlerIntegrationConfig.class);

    private BrokerService activeMQBroker;

    private int port;
    public CustomEventListener customEventListener;
    public volatile boolean running =false;

    public StompBrokerRelayMessageHandlerIntegrationConfig(CustomEventListener customEventListener){
        this.customEventListener=customEventListener;
    }

    public void setup() throws Exception {
        this.port = 61613;
        startActiveMQBroker();
//        customEventListener.expectBrokerAvailabilityEvent(true);  20s wait time is slow .
    }

    private void startActiveMQBroker() throws Exception {
        this.activeMQBroker = new BrokerService();
        this.activeMQBroker.addConnector("stomp://localhost:" + this.port);
        this.activeMQBroker.setStartAsync(false);
        this.activeMQBroker.setPersistent(false);
        this.activeMQBroker.setUseJmx(false);
        this.activeMQBroker.getSystemUsage().getMemoryUsage().setLimit(1024 * 1024 * 5);
        this.activeMQBroker.getSystemUsage().getTempUsage().setLimit(1024 * 1024 * 5);
        this.activeMQBroker.start();
        this.running = true;
    }

    @SneakyThrows
    @Override
    public void start() {
        logger.info("start the brokerService...");
        setup();

    }

    @SneakyThrows
    @Override
    public void stop() {
        logger.debug("Stopping ActiveMQ broker and will await shutdown");
        if (!this.activeMQBroker.isStarted()) {
            logger.debug("Broker not running");
            return;
        }
        final CountDownLatch latch = new CountDownLatch(1);
        this.activeMQBroker.addShutdownHook(latch::countDown);
        this.activeMQBroker.stop();
        Assert.isTrue(latch.await(5, TimeUnit.SECONDS),"Broker did not stop");
        logger.debug("Broker stopped");
    }

    @Override
    public boolean isAutoStartup() {
        return SmartLifecycle.super.isAutoStartup();
    }

    @Override
    public boolean isRunning() {
        return running;
    }


    @Override
    public int getPhase() {
        return Integer.MAX_VALUE-2;
    }
}
